
#include "Shield.h"
#include "Ship.h"
#include "Graphics/ParticleSystem/ParticleSystem.h"
#include "Graphics/ParticleSystem/ParticleEmitter.h"
#include "Graphics/ParticleSystem/OneTimeParticleEmitter.h"
#include "Graphics/ParticleSystem/ParticleModifier.h"
#include "Graphics/ParticleSystem/SphereRepulsorModifier.h"
#include "Graphics/ParticleSystem/PointAttractorModifier.h"

#include <list>
#include <GL/gl.h>
#include <cassert>
#include <cmath>
#include <iostream>


Shield::Shield(Ship *pship) :
    parent_ship(pship) {

    assert(parent_ship != NULL);
}


Shield::~Shield(){
    std::list<ParticleSystem*>::iterator it = spalling.begin();
    while(it != spalling.end()){
        delete *it;
        ++it;
    }
}


void Shield::render(void){
    glPushMatrix();
    glRotatef(-parent_ship->getRotation(), 0.0f, 0.0f, 1.0f);
/*
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    glColor4f(1.0f, 1.0f, 1.0f, 0.05f);

    // Draw the circular shield around the ship
    glBegin(GL_LINE_STRIP);
    for(unsigned i = 0; i <= 50; i++){
      float theta = M_PI*2.0f*i/50.0f;
      glVertex3f(sin(theta)*parent_ship->getSize(), cos(theta)*parent_ship->getSize(), 0.0f);
    }
    glEnd();
    glDisable(GL_BLEND);
*/

    std::list<ParticleSystem*>::iterator it = spalling.begin();
    while(it != spalling.end()){
        (*it)->render();
        ++it;
    }

    glPopMatrix();
}


void Shield::update(void){
    std::list<ParticleSystem*>::iterator it = spalling.begin();
    while(it != spalling.end()){
        (*it)->update();
        ++it;
    }

    removeInactiveSpall();
}


void Shield::energise(Vector2D contact_point){
    OneTimeParticleEmitter *spall_emitter = new OneTimeParticleEmitter(50, contact_point, 
                                                                       -1.0f*contact_point, 
                                                                       0.0f, 0.5f,
                                                            /*Colour*/ 0.2f, 1.0f, 0.2f, 
                                                                       1.0f, 0.1f, 
                                                            /*Size*/   0.1f, 0.0f,//0.075f, 0.0f, 
                                                                       1.5f, 0.5f, 
                                                                       0.0f, 0.0f,
                                                                       "data/Cloud.png");
    SphereRepulsorModifier *spall_repulsor = 
        new SphereRepulsorModifier(Vector2D(0.0f, 0.0f), parent_ship->getSize());

    PointAttractorModifier *attractor = new PointAttractorModifier(Vector2D(0.0f, 0.0f), 0.3f);

    std::vector<ParticleEmitter*> emitters;
    emitters.push_back(spall_emitter);

    std::vector<ParticleModifier*> modifiers;
    modifiers.push_back(spall_repulsor);
    modifiers.push_back(attractor);

    ParticleSystem *spall_psys = new ParticleSystem(emitters, modifiers);
    spalling.push_back(spall_psys);
}


void Shield::removeInactiveSpall(void){
    std::list<ParticleSystem*>::iterator it = spalling.begin();
    while(it != spalling.end()){
        if((*it)->active()){
            ++it;
        }
        else{
            delete *it;
            it = spalling.erase(it);
        }
    }
}

